<template>
  <div>
    <el-button @click="drawPoint">画点</el-button>
    <el-button @click="drawLine">画线</el-button>
    <el-button @click="drawPolygon">画面</el-button>
    <el-button :type="'primary'" @click="handleConfirm">确定</el-button>
    <el-button :type="'danger'" @click="handleClear">清除</el-button>
    <el-divider direction="vertical"></el-divider>
    <span>单击按钮开始绘制，双击地图任意位置结束绘制</span>
    <el-divider/>

    <div id="Map" style="width: 100%;height: 70vh"></div>
  </div>

</template>

<script>
import L from "leaflet"
import "leaflet/dist/leaflet.css"
export default {
  name: "Map",
  props:{
    geomJson:{}
  },
  computed:{
    geomJsonToLayerFn(){
      if (this.geomJson){
        //通过计算属性将字符串转为geoJson，并赋值给已加载的geoJson要素集
        let geojson = JSON.parse(this.geomJson)
        let geoJsonLayer = L.geoJson(geojson)
        this.featureCollection = geoJsonLayer.toGeoJSON()
        return geoJsonLayer
      }
    }
  },
  watch:{
    geomJsonToLayerFn(n,o){
      //TODO 很奇怪，点击修改的时候会触发两次这个监听
      if (n){
        n.addTo(this.map)
        this.featureCollection = n.toGeoJSON()
      }else if (o){
        this.featureCollection = {
          "type": "FeatureCollection",
          "features": []
        }
        this.map.removeLayer(o)
      }
    }
  },
  data(){
    return {
      map: null,
      drawingPoint: false,
      drawingLine: false,
      drawingPolygon: false,
      //编辑好的几何图形
      featureCollection: {
        "type": "FeatureCollection",
        "features": []
      },
    }
  },
  mounted() {
    this.initMap()
  },
  methods:{
    //初始化地图
    initMap() {
      //创建地图
      let map = L.map("Map", {
        center: [26.075302, 119.306239], // 中心位置
        zoom: 12, // 缩放等级
        attributionControl: true, // 版权控件
        zoomControl: true //缩放控件
      });
      //引用到本vue中定义的map变量
      this.map = map;
      //使用服务添加底图到地图
      L.tileLayer(
          "http://rt0.map.gtimg.com/realtimerender?z={z}&x={x}&y={-y}&type=vector&style=0"
      ).addTo(this.map) // 加载底图
      this.geomJsonToLayerFn.addTo(this.map)

    },
    //画点
    drawPoint(){
      let map = this.map;
      let featureCollection = this.featureCollection
      map.off("click")
      //定义点击事件
      map.on("click",function(e){
        //创建点的图标
        let icon = L.icon({
          iconUrl: '/favicon.ico',
        });
        //创建点（标记），用点击事件的经纬度赋值
        let marker = L.marker([e.latlng.lat,e.latlng.lng],{
          icon:icon,
        });
        //添加点到地图
        marker.addTo(map)
      //保存画好的点
        featureCollection.features.push(marker.toGeoJSON())
      })
    },
    //画线
    drawLine(){
      let featureCollection = this.featureCollection
      //点集
      var points=[]
      //创建线
      var lines=new L.polyline(points)
      //防止产生异步问题，应用this.map到drawLine函数内的新对象
      let map = this.map;
      //关闭旧双击事件，不关闭会导致双击放大地图
      map.off("dblclick")
      //鼠标移动事件
      const onMouseMove = (e)=>{
        //解构已有坐标点集，加入事件坐标，重新给线设置点集
        lines.setLatLngs([...points,[e.latlng.lat,e.latlng.lng]])
        //添加线到图层
        map.addLayer(lines)
      }
      //鼠标单击事件
      const onClick = function(e){
        //添加点击的坐标到生成线的点集
        points.push([e.latlng.lat,e.latlng.lng])
        //添加点到线的点集中
        lines.addLatLng(e.latlng)
        //添加线到图层
        map.addLayer(lines)
        //添加点击的点到图层，以红色点的样式
        map.addLayer(L.circle(e.latlng,{color:'#ff0000',fillColor:'ff0000',fillOpacity:1}))
        //绑定鼠标移动事件到地图
        map.on('mousemove',onMouseMove)
      }
      //鼠标双击事件，关闭所有事件
      const onDblClick = function(e){
        map.off('click')
        map.off('mousemove')
        featureCollection.features.push(lines.toGeoJSON())
      }
      //监听鼠标事件
      map.on("click",onClick)
      map.on("dblclick",onDblClick)
    },
    //画面
    drawPolygon(){
      let map = this.map
      let featureCollection = this.featureCollection
      //关闭旧双击事件，不关闭会导致双击放大地图
      map.off("dblclick")
      //新建一个多边形
      let latlng = []
      let polygon = L.polygon(latlng, { color: '#2d6bb2', fillColor: '#398ce8', fillOpacity: 0.5 })
      //鼠标移动事件
      const onMouseMove = (event)=>{
        //将已经点击的坐标点解构，加入移动中的鼠标的坐标，展示在地图上
        polygon.setLatLngs([...latlng, [event.latlng.lat, event.latlng.lng]])
        //添加到图层
        map.addLayer(polygon)
      }

      //点击事件
      const onClick = (event)=>{
        //往多边形添加点
        latlng.push([event.latlng.lat,event.latlng.lng])
        //重新设置经纬度点集
        polygon.setLatLngs(latlng)
        //添加到图层
        map.addLayer(polygon)
        //绑定鼠标移动事件
        map.on('mousemove',onMouseMove)
      }
      //双击事件
      const onDbClick = (event)=>{
        //关闭事件
        map.off('click')
        map.off('mousemove')
        featureCollection.features.push(polygon.toGeoJSON())
      }
      //给地图绑定事件
      map.on('click',onClick)
      map.on('dblclick',onDbClick)

    },
    //确定
    handleConfirm(){
      this.$emit('mapConfirm',this.featureCollection)
    },
    handleClear(){
      this.map.removeLayer(this.geomJsonToLayerFn)
      // this.geomJson = null
      this.featureCollection = {
        "type": "FeatureCollection",
        "features": []
      }
    }
  }

}
</script>

<style scoped>

</style>
